﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include "GmepModelInterface.h"

namespace gcmp
{
    class UniIdentity;
    class IDocument;
    class IParameterDefinition;
}

namespace gmep
{
    enum class UnitCategory;
    enum class DigitGroupingType;
    struct UnitItem;
    class IUnitConverter;
    struct UnitConverterInputForTag;
    class GMEP_MODEL_INTERFACE_EXPORT GmepUnitUtils
    {
    public:
        static void InitializeParameterDisplay(gcmp::IDocument* pDocument);

        /// \brief 获取单位项的中文名
        ///
        /// \param UnitCategory unitCategory 单位类别
        /// \param int unitIndex 单位项的下标
        /// \return std::wstring 返回单位项的中文名
        static std::wstring GetUnitStringCHN(UnitCategory unitCategory, int unitIndex);

        /// \brief 获取单位项的符号
        ///
        /// \param UnitCategory unitCategory 单位类别
        /// \param int unitIndex 单位项的下标
        /// \param int symbolIndex 单位符号的下标
        /// \return std::wstring 返回单位项的符号
        static std::wstring GetUnitSymbol(UnitCategory unitCategory, int unitIndex, int symbolIndex);

        /// \brief 获得经精度和数位分组处理后的数值的字符串
        ///
        /// \param double value 待处理的数值
        /// \param double precision 精度
        /// \param DigitGroupingType digitGroupingType 数位分组类型
        /// \return std::wstring 返回处理后的数值的字符串
        static std::wstring GetDisplayValueString(double value, double precision, DigitGroupingType digitGroupingType);

        /// \brief 将一个拥有单位的参数转换成用户定义的单位
        ///
        /// \param gcmp::UniIdentity gmepUnitType gmep定义的单位GUID，例如UNIT(GmepLength)，可通过IParameterDefinition->GetUnitTypeId()获得
        /// \param double originValue 原始参数的参数值
        /// \param int originUnit 原始参数的单位枚举值
        /// \return std::wstring 转换成用户定义单位后的参数字符串，如 123.45 mm
        static std::wstring ConvertToCustonUnitString(gcmp::IDocument *pDoc, gcmp::UniIdentity gmepUnitType, double originValue, int originUnit);

        /// \brief 将一个拥有单位的参数数值转换成Gmep内部标准单位
        ///
        /// \param gcmp::UniIdentity gmepUnitType gmep定义的单位GUID，例如UNIT(GmepLength)，可通过IParameterDefinition->GetUnitTypeId()获得
        /// \param double originValue 原始参数的参数值
        /// \param int originUnit 原始参数的单位枚举值
        /// \return double 转换成标准单位后的参数值
        static double ConvertToStandardUnitValue(gcmp::IDocument *pDoc, gcmp::UniIdentity gmepUnitType, double originValue, int originUnit);
        
        /// \brief 将一个用户输入的字符串解析成数值和单位
        ///
        /// \param const std::wstring &displayString 用户输入的字符串
        /// \param const std::vector<UnitItem>& unitItems 该单位所有的单位项
        /// \param int &unitIndex 返回解析得到的单位项下标，若字符串为纯数值，则为-1
        /// \param double &value 返回解析得到的数值
        /// \return bool 是否解析成功。当字符串不合法、字符串中所含单位不在可选单位项中时，解析失败
        static bool ParseDisplayString(const std::wstring &displayString, const std::vector<UnitItem>& unitItems, int &unitIndex, double &value);

        /// \brief 根据单位以及tag的相关参数，根据单位设置，返回tag的相应的显示值
        /// \param pConverter 单位转换器
        /// \param input tag相关参数的关于单位的输入数据
        /// \retrun 返回根据单位相关设置，转换后的带单位信息的值
        static std::wstring GetDisplayStringByValue(const IUnitConverter* pConverter,const UnitConverterInputForTag& input);

        /// \brief 根据参数定义，获取正确的单位类型（GCMP刷新参数时会将机电定义的参数信息覆盖）
        /// \param pParameterDefinition 参数定义
        /// \retrun 返回根据参数定义，获取的正确单位类型
        static gcmp::UniIdentity GetGmepUnitType(const gcmp::IParameterDefinition* pParameterDefinition);
    };
}
